Most Oberon viewers have 2 frames (a menu frame and a contents frame). Such viewers are opened with MenuViewers.New instead of Viewers.Open. MenuViewers.New needs the following parameters:
- a menu frame
- a contents frame
- the height of the menu (usually always TextFrames.menuH)
- the coordinates of a point on the upper edge of the new viewer
---------------
Palatino10.Scn.Fnt
Palatino10i.Scn.Fnt
---------------
A viewer is normally closed interactively with the command System.Close. It can, however, also be closed from a program with Viewers.Close. The contents of the viewer is not saved automatically. A viewer that was closed unintentionally can be reopened with the command System.Recall.
---------------
MarkElems
Alloc
Palatino10.Scn.Fnt
Syntax10.Scn.Fnt
Palatino10i.Scn.Fnt
FoldElems
Syntax10.Scn.Fnt
Viewers.This(x, 0)
Syntax10.Scn.Fnt
v.state > 1
Syntax10.Scn.Fnt
Viewers.Next(v)
Syntax10.Scn.Fnt
x + v.W
---------------
This can be useful for finding a specific viewer or a viewer with a certain contents.
PROCEDURE TraverseAllViewers;
VAR x: INTEGER; v: Viewers.Viewer;
BEGIN
x := 0;
WHILE x < Display.Width DO
v :=
bottom viewer in x track
WHILE
v is not the filler viewer
(*... process viewer v ...*)
v :=
viewer above v
END;
x :=
x of next track
END TraverseAllViewers;
---------------
Palatino10.Scn.Fnt
---------------
This message is normally forwarded to the frames of the viewer.
---------------
Palatino10.Scn.Fnt
LinkElems
Alloc
MyProg.Guide.Text
Palatino10i.Scn.Fnt
Syntax10.Scn.Fnt
---------------
Traverse all viewers on the screen (
) and find the one with the smallest value of
v.dsc.next(TextFrames.Frame).time.
---------------
Text1
Palatino14b.Scn.Fnt
Syntax10.Scn.Fnt
StyleElems
Alloc
TwoCols
Palatino10.Scn.Fnt
LinkElems
Alloc
Prog.Guide.Text
Prog.Guide.Text
Palatino10i.Scn.Fnt
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Position of star-shaped pointer x := Oberon.Pointer.X;
y := Oberon.Pointer.Y;
The marked viewer Oberon.MarkedViewer()
Position of the mouse x := Oberon.Mouse.X;
y := Oberon.Mouse.Y;
Viewer which contains mouse Viewers.This(Oberon.Mouse.X, Oberon.Mouse.Y)
Focus viewer Oberon.FocusViewer
Is viewer v a standard text viewer? IF (v IS MenuViewers.Viewer) &
(v.dsc IS TextFrames.Frame) &
(v.dsc.next IS TextFrames.Frame) THEN ...
Has viewer v a text frame as menu frame? IF v.dsc IS TextFrames.Frame THEN ...
Has viewer v a text frame as main frame? IF (v.dsc # NIL) &
(v.dsc.next IS TextFrames.Frame) THEN ...
The menu frame of a text viewer v v.dsc(TextFrames.Frame)
The menu text of a text viewer v v.dsc(TextFrames.Frame).text
The main frame of a text viewer v v.dsc.next(TextFrames.Frame)
The main text of a text viewer v v.dsc.next(TextFrames.Frame).text
The most recent selection Oberon.GetSelection(text, beg, end, time)
Is the command executed from the menu v := Oberon.Par.vwr;
frame? IF (Oberon.Par.frame IS TextFrames.Frame) &
(v.dsc = Oberon.Par.frame) THEN ...
Placement of the viewer in the user track Oberon.AllocateUserViewer(
of the display which contains the mouse Oberon.Mouse.X, x, y)
Placement of the viewer in the system track Oberon.AllocateSystemViewer(
of the display which contains the mouse Oberon.Mouse.X, x, y)
Open a new text viewer: x and y are text := TextFrames.Text(name);
determined by AllocateUserViewer or v := MenuViewers.New(
A caret is set in text frame f IF f.hasCar THEN ...
Position of the caret, if one is set IF f.hasCar THEN pos := f.carloc.pos END;
A selection exists in text frame f IF f.hasSel THEN ...
Start of the selection, if one exists IF f.hasSel THEN pos := f.selbeg.pos END;
End of the selection, if one exists IF f.hasSel THEN pos := f.selend.pos END;
Set the caret at pos in text frame f Oberon.PassFocus(v);
installed in menu viewer v TextFrames.SetCaret(f, beg, end);
Select stretch [beg, end) in text frame f TextFrames.SetSelection(f, beg, end);
Scroll text such that line with origin at org TextFrames.RemoveSelection(f);
will be displayed on top of the viewer TextFrames.RemoveCaret(f);
Oberon.RemoveMarks(f.X, f.Y, f.W, f.H);
TextFrames.Show(f, org);
Delete the selected text in the marked viewer
Copy the most recent selection to the caret's position
A caret is only allowed if the viewer which manages the frame is the focus viewer.
If a caret is displayed (f.car > 0), it must be removed prior to using TextFrames.SetCaret.
Prior to using TextFrames.Show, the caret, the selection, the mouse cursor, and the pointer must be removed.
The Caret is removed either by a call of TextFrames.RemoveCaret(f) or as a consequence of Oberon.PassFocus(v).
Text1
Palatino14b.Scn.Fnt
Syntax10.Scn.Fnt
StyleElems
Alloc
TwoCols
Palatino10.Scn.Fnt
Palatino10i.Scn.Fnt
LinkElems
Alloc
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Prog.Guide.Text
Open a new file name f := Files.New(name);
Open an existing file name f := Files.Old(name);
Write buffers to disk sectors Files.Close(f);
Write buffers to disk and register file f in directory Files.Register(f);
Sequential read access through rider r Files.Set(r, f, 0);
Files.Read(r, ch); Files.Read(r, ch);
Sequential write access through rider r Files.Set(r, f, 0);
Files.Write(r, ch); Files.Write(r, ch);
Random access at position pos Files.Set(r, f, pos);
Files.Read(r, ch); ... Files.Write(r, ch);
Read/write a record a of type T Files.ReadBytes(r, a, SIZE(T));
Files.WriteBytes(r, a, SIZE(T));
Read/write a record of type T accessed Files.ReadBytes(r, p^, SIZE(T));
with a pointer p Files.WriteBytes(r, p^, SIZE(T));
Opening another rider for the same file Files.Set(newR, Files.Base(r), Files.Pos(r))
Text1
Text1
Palatino14b.Scn.Fnt
Syntax10.Scn.Fnt
StyleElems
Alloc
Text2
Palatino10.Scn.Fnt
Palatino10i.Scn.Fnt
TwoCols
Module In provides a set of basic routines for formatted input of characters, character sequences, numbers, and names. It assumes a standard input stream with a current position that can be reset. Usually the input stream is the text immediately following the most recently invoked command. If this text starts with the character ^ the current position is set to the beginning of the most recent selection (if no selection exists, Done is set to FALSE). If the text starts with the character * the current position is set to the beginning of the text in the marked viewer (if no viewer is marked, Done is set to FALSE). The end of the input stream is the end of the text containing the current position.
Start reading process In.Open or In.OpenText(t, pos)
Read a character In.Char(ch)
Usually you want to skip leading blanks WHILE In.Done & (ch = " ") DO In.Char(ch) END;
Read an integer number In.Int(i) or In.LongInt(li)
Read a real number In.Real(r) or In.LongReal(lr)
Read a name or a string In.Name(s) or In.String(s)
Read next symbol IF In.Next() = In.name THEN
In.char, In.int, In.name, In.string, In.Name(s)
In.real, In.longReal, ELSIF In.Next() = In.string THEN
and In.inval In.String(s)
ELSE ...
Determine success of the last operation IF In.Done THEN ...
Text1
Palatino14b.Scn.Fnt
Syntax10.Scn.Fnt
StyleElems
Alloc
Text2
Palatino10.Scn.Fnt
Palatino10i.Scn.Fnt
TwoCols
Module Out provides a set of basic routines for formatted output of characters, numbers, and strings. It assumes a standard output stream to which the symbols are written.
Start writing process
Usually you want to write into the system log which does not need an Out.Open call.
Open a new output viewer Out.Open
Redirect output to System.Log again Out.Close
Write a character Out.Char(ch)
Write an integer number Out.Int(i, 0)
... within 10 characters Out.Int(i, 10)
Write a real number Out.Real(r, 0) or Out.LongReal(lr, 0)
Write a string Out.String(s)
Write a new line character Out.Ln
Write a string containing one integer number Out.F("$Value of x: #", x)
(* Searches a text from the initial position pos for the first occurrence of an italics font. It returns this position, if it exists, otherwise -1 results. *)
(* When scanning a whole text, you can use ~s.eot as predicate in a WHILE loop as above, but s.eot may already yield TRUE while the last valid symbol is returned, not only after an attempt to scan beyond the end of the text. In this case, a WHILE loop using the predicate ~s.eot misses the last symbol. Therefore, it is always preferable to terminate a sequence of scan operations with a definite symbol. *)
PROCEDURE PutInt* (txt: ARRAY OF CHAR; i: LONGINT);
PROCEDURE ProcessNames*; (* {name} ~ *)
PROCEDURE ProcessSelection*; (* ^ *)
PROCEDURE ProcessArgs*; (* {name} ~ | ^ *)
PROCEDURE Close*; (* * *)
PROCEDURE CloseVisible*; (* * *)
(* Copies the font of the character underneath the star-shaped pointer to the selection *)
PROCEDURE CopyFont*;
PROCEDURE OpenViewer*;
(* If the command is issued from an editable text, it admits a parameter list. All texts in the list will be processed. If, on the other hand, ProcessText2 is issued from the menu, it will work on the text contained in the main frame of the viewer which contains the menu. *)
PROCEDURE ProcessText2*;
(* The following code is what Edit.Recall actually does. *)
PROCEDURE Recall*;
(* The text of the main frame of the marked viewer is searched for the occurrence of a character in italics font Syntax10i.Scn.Fnt. The search is started at the caret position or at the beginning of the text if not caret is set. If a character is located, the text is scrolled such that it is displayed near the top line and the caret is positioned. *)
PROCEDURE SearchItalics*;
(* Try to open an old file, if none exists, create a new one *)
PROCEDURE ProcessFile (name: ARRAY OF CHAR);
PROCEDURE Backup (VAR name, bak: ARRAY OF CHAR);
PROCEDURE Save (name: ARRAY OF CHAR);
PROCEDURE RecordFile;
(* Deletes the selected text in the marked viewer. *)
PROCEDURE Delete*;
(* Copies the most recently selected text part to the caret's position. *)
PROCEDURE CopyText*;
(* Tracks the mouse and process the mouse keys and the position *)
PROCEDURE TrackMouse (VAR keysum: SET; VAR x, y: INTEGER);
(* Try to read a character from keyboard *)
PROCEDURE ReadChar (VAR ch: CHAR): BOOLEAN;
BEGIN
Texts.OpenWriter(w) (* The writer is based on the file system. In most cases, one writer per module is enough. It is, therefore, good practice to open the writer once per session in the module's body. *)